home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 2
/
Deutsche Edition 2.iso
/
mac
/
POWERMAC
/
C64
/
SOURCE
/
CpuC.c
< prev
next >
Wrap
Text File
|
1994-06-06
|
17KB
|
939 lines
/*
Commodore 64 Emulator v0.4 Earle F. Philhower III
Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Processor.h"
#include "NewInstructions.h"
#include "Stack.h"
#include "Modes.h"
#include "Error.h"
extern byte bcd2dec[], dec2bcd[], cycletime[], scanCode[];
/*
This is my Instructions.c file condensed into one single routine.
*/
void IntegratedProcessor(byte *Ga, byte *Gx, byte *Gy, byte *Gflags, byte *Gsp, word *Gpc,
byte **Gmemory, byte *GRAM)
{
/*
First we make local copies of the global variables. These *should* be stored
within a register variable, but with TC, who knows!
*/
register byte a, x, y, flags, sp;
register word pc;
register byte **memory, **memoryp1, *RAM;
register byte tbyte;
register word addr;
int cycles, lines;
byte oldMemoryMap;
a=*Ga; x=*Gx; y=*Gy; flags=*Gflags; sp=*Gsp; pc=*Gpc;
memory=Gmemory; memoryp1=memory+1; RAM=GRAM;
oldMemoryMap=*RAMp1;
lines=0;
while (++lines<350)
{
cycles=0;
while (cycles<35)
{
tbyte=ImmediateByte(); pc++;
cycles+=cycletime[tbyte];
switch (tbyte)
{
case 0x00:
PushWord(pc);
flags |= BKC;
Push(flags|BKC);
pc=WordAt(IrqTo);
break;
case 0x01:
ORA(IndirectXAddr); pc++;
break;
case 0x02:
CRS();
break;
case 0x03:
LOR(IndirectXAddr); pc++;
break;
case 0x04:
SKP(1);
break;
case 0x05:
ORA(ZeroPageAddr); pc++;
break;
case 0x06:
ASL(ZeroPageAddr); pc++;
break;
case 0x07:
LOR(ZeroPageAddr); pc++;
break;
case 0x08:
Push(flags);
break;
case 0x09:
a |= ImmediateByte(); FlagsNZ(a); pc++;
break;
case 0x0a:
if (a&128) flags |= CAR;
else flags &= ~CAR;
a=a<<1;
FlagsNZ(a);
break;
case 0x0b:
ANA(); pc++;
break;
case 0x0c:
SKP(2);
break;
case 0x0d:
ORA(AbsoluteAddr); pc+=2;
break;
case 0x0e:
ASL(AbsoluteAddr); pc+=2;
break;
case 0x0f:
LOR(AbsoluteAddr); pc+=2;
break;
case 0x10:
BCL(NEG);
break;
case 0x11:
ORA(IndirectYAddr); pc++;
break;
case 0x12:
CRS();
break;
case 0x13:
LOR(IndirectYAddr); pc++;
break;
case 0x14:
SKP(1);
break;
case 0x15:
ORA(ZeroPageXAddr); pc++;
break;
case 0x16:
ASL(ZeroPageXAddr); pc++;
break;
case 0x17:
LOR(ZeroPageXAddr); pc++;
break;
case 0x18:
CLR(CAR);
break;
case 0x19:
ORA(AbsoluteYAddr); pc+=2;
break;
case 0x1a:
pc++;
break;
case 0x1b:
LOR(AbsoluteYAddr); pc+=2;
break;
case 0x1c:
SKP(2);
break;
case 0x1d:
ORA(AbsoluteXAddr); pc+=2;
break;
case 0x1e:
ASL(AbsoluteXAddr); pc+=2;
break;
case 0x1f:
LOR(AbsoluteXAddr); pc+=2;
break;
case 0x20:
PushWord(pc+1); pc=WordAt(pc);
break;
case 0x21:
AND(IndirectXAddr); pc++;
break;
case 0x22:
CRS();
break;
case 0x23:
LAN(IndirectXAddr); pc+=2;
break;
case 0x24:
BIT(ZeroPageAddr); pc++;
break;
case 0x25:
AND(ZeroPageAddr); pc++;
break;
case 0x26:
ROL(ZeroPageAddr); pc++;
break;
case 0x27:
LAN(ZeroPageAddr); pc++;
break;
case 0x28:
flags = Pop();
break;
case 0x29:
a &= ImmediateByte(); FlagsNZ(a); pc++;
break;
case 0x2a:
if (flags&CAR) {
if ((a&128)==0) flags &=~CAR;
a=(a<<1)|1; }
else {
if(a&128)flags|=CAR;
a=a<<1; }
FlagsNZ(a);
break;
case 0x2b:
ANA(); pc++;
break;
case 0x2c:
BIT(AbsoluteAddr); pc+=2;
break;
case 0x2d:
AND(AbsoluteAddr); pc+=2;
break;
case 0x2e:
ROL(AbsoluteAddr); pc+=2;
break;
case 0x2f:
LAN(AbsoluteAddr); pc+=2;
break;
case 0x30:
BST(NEG);
break;
case 0x31:
AND(IndirectYAddr); pc++;
break;
case 0x32:
CRS();
break;
case 0x33:
LAN(IndirectYAddr); pc+=2;
break;
case 0x34:
SKP(1);
break;
case 0x35:
AND(ZeroPageXAddr); pc++;
break;
case 0x36:
ROL(ZeroPageXAddr); pc++;
break;
case 0x37:
LAN(ZeroPageXAddr); pc++;
break;
case 0x38:
SET(CAR);
break;
case 0x39:
AND(AbsoluteYAddr); pc+=2;
break;
case 0x3a:
pc++;
break;
case 0x3b:
LAN(AbsoluteYAddr); pc+=2;
break;
case 0x3c:
SKP(2);
break;
case 0x3d:
AND(AbsoluteXAddr); pc+=2;
break;
case 0x3e:
ROL(AbsoluteXAddr); pc+=2;
break;
case 0x3f:
LAN(AbsoluteXAddr); pc+=2;
break;
case 0x40:
flags=Pop(); PopWord(pc);
break;
case 0x41:
EOR(IndirectXAddr); pc++;
break;
case 0x42:
CRS();
break;
case 0x43:
REO(IndirectXAddr); pc+=2;
break;
case 0x44:
SKP(1);
break;
case 0x45:
EOR(ZeroPageAddr); pc++;
break;
case 0x46:
LSR(ZeroPageAddr); pc++;
break;
case 0x47:
REO(ZeroPageAddr); pc++;
break;
case 0x48:
Push(a);
break;
case 0x49:
a ^= ImmediateByte(); FlagsNZ(a); pc++;
break;
case 0x4a:
flags &=~(CAR+NEG+ZER);
if (a&1) flags |=CAR;
if (a=a>>1); else flags |=ZER;
break;
case 0x4b:
RBM(); pc++;
break;
case 0x4c:
pc=WordAt(pc);
break;
case 0x4d:
EOR(AbsoluteAddr); pc+=2;
break;
case 0x4e:
LSR(AbsoluteAddr); pc+=2;
break;
case 0x4f:
REO(AbsoluteAddr); pc+=2;
break;
case 0x50:
BCL(OVF);
break;
case 0x51:
EOR(IndirectYAddr); pc++;
break;
case 0x52:
CRS();
break;
case 0x53:
REO(IndirectYAddr); pc+=2;
break;
case 0x54:
SKP(1);
break;
case 0x55:
EOR(ZeroPageXAddr); pc++;
break;
case 0x56:
LSR(ZeroPageXAddr); pc++;
break;
case 0x57:
REO(ZeroPageXAddr); pc++;
break;
case 0x58:
CLR(INT);
break;
case 0x59:
EOR(AbsoluteYAddr); pc+=2;
break;
case 0x5a:
pc++;
break;
case 0x5b:
REO(AbsoluteYAddr); pc+=2;
break;
case 0x5c:
SKP(2);
break;
case 0x5d:
EOR(AbsoluteXAddr); pc+=2;
break;
case 0x5e:
LSR(AbsoluteXAddr); pc+=2;
break;
case 0x5f:
REO(AbsoluteXAddr); pc+=2;
break;
case 0x60:
PopWord(pc); pc++;
break;
case 0x61:
ADC(IndirectXAddr); pc++;
break;
case 0x62:
CRS();
break;
case 0x63:
RAD(IndirectXAddr); pc++;
break;
case 0x64:
SKP(1);
break;
case 0x65:
ADC(ZeroPageAddr); pc++;
break;
case 0x66:
ROR(ZeroPageAddr); pc++;
break;
case 0x67:
RAD(ZeroPageAddr); pc++;
break;
case 0x68:
a=Pop(); FlagsNZ(a);
break;
case 0x69:
addr=ImmediateByte();
if (flags&DEC) {
addr = bcd2dec[addr]+bcd2dec[a]+((flags&CAR)?1:0);
flags &= ~(CAR+OVF+NEG+ZER);
if (addr>99) {
flags|=CAR+OVF;
addr -=100; }
if (addr==0) flags |= ZER;
else flags |= addr&128;
a=dec2bcd[addr];}
else {
addr += a+((flags&CAR)?1:0);
flags &= ~(CAR+OVF+NEG+ZER);
if (addr>255) {
flags|=OVF+CAR;
addr &=255; }
if (addr==0) flags |= ZER;
else flags |= addr&128;
a=addr; }
pc++;
break;
case 0x6a:
if (flags&CAR) {
if ((a&1)==0) flags &=~CAR;
a=(a>>1)|128; }
else {
if(a&1) flags|=CAR;
a=a>>1; }
FlagsNZ(a);
break;
case 0x6b:
RMAM(); pc++;
break;
case 0x6c:
addr=WordAt(pc); pc=WordAt(addr);
break;
case 0x6d:
ADC(AbsoluteAddr); pc+=2;
break;
case 0x6e:
ROR(AbsoluteAddr); pc+=2;
break;
case 0x6f:
RAD(AbsoluteAddr); pc+=2;
break;
case 0x70:
BST(OVF);
break;
case 0x71:
ADC(IndirectYAddr); pc++;
break;
case 0x72:
CRS();
break;
case 0x73:
RAD(IndirectYAddr); pc++;
break;
case 0x74:
SKP(1);
break;
case 0x75:
ADC(ZeroPageXAddr); pc++;
break;
case 0x76:
ROR(ZeroPageXAddr); pc++;
break;
case 0x77:
RAD(ZeroPageXAddr); pc++;
break;
case 0x78:
SET(INT);
break;
case 0x79:
ADC(AbsoluteYAddr); pc+=2;
break;
case 0x7a:
pc++;
break;
case 0x7b:
RAD(AbsoluteYAddr); pc+=2;
break;
case 0x7c:
SKP(2);
break;
case 0x7d:
ADC(AbsoluteXAddr); pc+=2;
break;
case 0x7e:
ROR(AbsoluteXAddr); pc+=2;
break;
case 0x7f:
RAD(AbsoluteXAddr); pc+=2;
break;
case 0x80:
SKP(1);
break;
case 0x81:
STA(IndirectXAddr); pc++;
break;
case 0x82:
SKP(1);
break;
case 0x83:
AAX(IndirectXAddr); pc++;
break;
case 0x84:
STY(ZeroPageAddr); pc++;
break;
case 0x85:
STA(ZeroPageAddr); pc++;
break;
case 0x86:
STX(ZeroPageAddr); pc++;
break;
case 0x87:
AAX(ZeroPageAddr); pc+=1;
break;
case 0x88:
y--; FlagsNZ(y);
break;
case 0x89:
SKP(1);
break;
case 0x8a:
a=x; FlagsNZ(a);
break;
case 0x8b:
XMA(); pc++;
break;
case 0x8c:
STY(AbsoluteAddr); pc+=2;
break;
case 0x8d:
STA(AbsoluteAddr); pc+=2;
break;
case 0x8e:
STX(AbsoluteAddr); pc+=2;
break;
case 0x8f:
AAX(AbsoluteAddr); pc+=2;
break;
case 0x90:
BCL(CAR);
break;
case 0x91:
STA(IndirectYAddr); pc++;
break;
case 0x92:
CRS();
break;
case 0x93:
AAX(IndirectYAddr); pc++;
break;
case 0x94:
STY(ZeroPageXAddr); pc++;
break;
case 0x95:
STA(ZeroPageXAddr); pc++;
break;
case 0x96:
STX(ZeroPageYAddr); pc++;
break;
case 0x97:
AAX(ZeroPageYAddr); pc++;
break;
case 0x98:
a=y; FlagsNZ(a);
break;
case 0x99:
STA(AbsoluteYAddr); pc+=2;
break;
case 0x9a:
sp=x;
break;
case 0x9b:
AXS(AbsoluteYAddr); pc+=2;
break;
case 0x9c:
TEY(AbsoluteXAddr); pc+=2;
break;
case 0x9d:
STA(AbsoluteXAddr); pc+=2;
break;
case 0x9e:
TEX(AbsoluteYAddr); pc+=2;
break;
case 0x9f:
TEA(AbsoluteYAddr); pc+=2;
break;
case 0xa0:
y=ImmediateByte(); FlagsNZ(y); pc++;
break;
case 0xa1:
LDA(IndirectXAddr); pc++;
break;
case 0xa2:
x=ImmediateByte(); FlagsNZ(x); pc++;
break;
case 0xa3:
LAX(IndirectXAddr); pc++;
break;
case 0xa4:
LDY(ZeroPageAddr); pc++;
break;
case 0xa5:
LDA(ZeroPageAddr); pc++;
break;
case 0xa6:
LDX(ZeroPageAddr); pc++;
break;
case 0xa7:
LAX(ZeroPageAddr); pc++;
break;
case 0xa8:
y=a; FlagsNZ(y);
break;
case 0xa9:
a=ImmediateByte(); FlagsNZ(a); pc++;
break;
case 0xaa:
x=a; FlagsNZ(x);
break;
case 0xab:
AMA(); pc++;
break;
case 0xac:
LDY(AbsoluteAddr); pc+=2;
break;
case 0xad:
LDA(AbsoluteAddr); pc+=2;
break;
case 0xae:
LDX(AbsoluteAddr); pc+=2;
break;
case 0xaf:
LAX(AbsoluteAddr); pc+=2;
break;
case 0xb0:
BST(CAR);
break;
case 0xb1:
LDA(IndirectYAddr); pc++;
break;
case 0xb2:
CRS();
break;
case 0xb3:
LAX(IndirectYAddr); pc++;
break;
case 0xb4:
LDY(ZeroPageXAddr); pc++;
break;
case 0xb5:
LDA(ZeroPageXAddr); pc++;
break;
case 0xb6:
LDX(ZeroPageYAddr); pc++;
break;
case 0xb7:
LAX(ZeroPageYAddr); pc++;
break;
case 0xb8:
CLR(OVF);
break;
case 0xb9:
LDA(AbsoluteYAddr); pc+=2;
break;
case 0xba:
x=sp;
break;
case 0xbb:
LAS(AbsoluteYAddr); pc+=2;
break;
case 0xbc:
LDY(AbsoluteXAddr); pc+=2;
break;
case 0xbd:
LDA(AbsoluteXAddr); pc+=2;
break;
case 0xbe:
LDX(AbsoluteYAddr); pc+=2;
break;
case 0xbf:
LAX(AbsoluteYAddr); pc+=2;
break;
case 0xc0:
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (y==tbyte) flags |=CAR+ZER;
else if (y>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
break;
case 0xc1:
CMP(IndirectXAddr); pc++;
break;
case 0xc2:
SKP(1);
break;
case 0xc3:
DCP(IndirectXAddr); pc++;
break;
case 0xc4:
CPY(ZeroPageAddr); pc++;
break;
case 0xc5:
CMP(ZeroPageAddr); pc++;
break;
case 0xc6:
DECR(ZeroPageAddr); pc++;
break;
case 0xc7:
DCP(ZeroPageAddr); pc++;
break;
case 0xc8:
y++; FlagsNZ(y);
break;
case 0xc9:
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (a==tbyte) flags |=CAR+ZER;
else if (a>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
break;
case 0xca:
x--; FlagsNZ(x);
break;
case 0xcb:
AXM(); pc++;
break;
case 0xcc:
CPY(AbsoluteAddr); pc+=2;
break;
case 0xcd:
CMP(AbsoluteAddr); pc+=2;
break;
case 0xce:
DECR(AbsoluteAddr); pc+=2;
break;
case 0xcf:
DCP(AbsoluteAddr); pc++;
break;
case 0xd0:
BCL(ZER);
break;
case 0xd1:
CMP(IndirectYAddr); pc++;
break;
case 0xd2:
CRS();
break;
case 0xd3:
DCP(IndirectYAddr); pc++;
break;
case 0xd4:
SKP(1);
break;
case 0xd5:
CMP(ZeroPageXAddr); pc++;
break;
case 0xd6:
DECR(ZeroPageXAddr); pc++;
break;
case 0xd7:
DCP(ZeroPageXAddr); pc++;
break;
case 0xd8:
CLR(DEC);
break;
case 0xd9:
CMP(AbsoluteYAddr); pc+=2;
break;
case 0xda:
pc++;
break;
case 0xdb:
DCP(AbsoluteYAddr); pc++;
break;
case 0xdc:
SKP(2);
break;
case 0xdd:
CMP(AbsoluteXAddr); pc+=2;
break;
case 0xde:
DECR(AbsoluteXAddr); pc+=2;
break;
case 0xdf:
DCP(AbsoluteXAddr); pc++;
break;
case 0xe0:
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (x==tbyte) flags |=CAR+ZER;
else if (x>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
break;
case 0xe1:
SBC(IndirectXAddr); pc++;
break;
case 0xe2:
SKP(1);
break;
case 0xe3:
ISB(IndirectXAddr); pc++;
break;
case 0xe4:
CPX(ZeroPageAddr); pc++;
break;
case 0xe5:
SBC(ZeroPageAddr); pc++;
break;
case 0xe6:
INCR(ZeroPageAddr); pc++;
break;
case 0xe7:
ISB(ZeroPageAddr); pc++;
break;
case 0xe8:
x++; FlagsNZ(x);
break;
case 0xe9:
addr=ImmediateByte();
if (flags&DEC) {
addr = bcd2dec[a]-bcd2dec[addr]-((flags&CAR)?0:1);
flags &= ~(CAR+ZER+NEG+OVF);
if (addr==0) flags |=ZER+CAR;
else if (((int)addr)>0) flags |=CAR;
else {
flags|=NEG;
addr +=100; }
a=dec2bcd[addr]; }
else {
addr = a-addr-((flags&CAR)?0:1);
flags &=~(CAR+ZER+OVF+NEG);
if (addr==0) flags |= ZER+CAR;
else if (((int)addr)>0) flags |= CAR;
else flags|=OVF;
addr &= 255;
flags |= addr&128;
a=addr; }
pc++;
break;
case 0xea:
break;
case 0xeb:
addr=ImmediateByte();
if (flags&DEC) {
addr = bcd2dec[a]-bcd2dec[addr]-((flags&CAR)?0:1);
flags &= ~(CAR+ZER+NEG+OVF);
if (addr==0) flags |=ZER+CAR;
else if (((int)addr)>0) flags |=CAR;
else {
flags|=NEG;
addr +=100; }
a=dec2bcd[addr]; }
else {
addr = a-addr-((flags&CAR)?0:1);
flags &=~(CAR+ZER+OVF+NEG);
if (addr==0) flags |= ZER+CAR;
else if (((int)addr)>0) flags |= CAR;
else flags|=OVF;
addr &= 255;
flags |= addr&128;
a=addr; }
pc++;
break;
case 0xec:
CPX(AbsoluteAddr); pc+=2;
break;
case 0xed:
SBC(AbsoluteAddr); pc+=2;
break;
case 0xee:
INCR(AbsoluteAddr); pc+=2;
break;
case 0xef:
ISB(AbsoluteAddr); pc+=2;
break;
case 0xf0:
BST(ZER);
break;
case 0xf1:
SBC(IndirectYAddr); pc++;
break;
case 0xf2:
CRS();
break;
case 0xf3:
ISB(IndirectYAddr); pc++;
break;
case 0xf4:
SKP(1);
break;
case 0xf5:
SBC(ZeroPageXAddr); pc++;
break;
case 0xf6:
INCR(ZeroPageXAddr); pc++;
break;
case 0xf7:
ISB(ZeroPageXAddr); pc++;
break;
case 0xf8:
SET(DEC);
break;
case 0xf9:
SBC(AbsoluteYAddr); pc+=2;
break;
case 0xfa:
pc++;
break;
case 0xfb:
ISB(AbsoluteYAddr); pc+=2;
break;
case 0xfc:
SKP(2);
break;
case 0xfd:
SBC(AbsoluteXAddr); pc+=2;
break;
case 0xfe:
INCR(AbsoluteXAddr); pc+=2;
break;
case 0xff:
/*
This is out TRAP command for patching the ROMs. First make sure
the global registers are set properly
*/
*Ga=a; *Gx=x; *Gy=y; *Gflags=flags; *Gsp=sp; *Gpc=pc;
TrapExecute();
a=*Ga; x=*Gx; y=*Gy; flags=*Gflags; sp=*Gsp; pc=*Gpc;
break;
}
/* Set up the keyboard register according to precomputed values */
RAM[0xdc01]=scanCode[RAM[0xdc00]];
}
if (++RAM[0xd012]==0) RAM[0xd011] ^= 128;
RAM[0xd018] |=1;
}
*Ga=a; *Gx=x; *Gy=y; *Gflags=flags; *Gsp=sp; *Gpc=pc;
}